為了支援 State Level,我們在 State 裡面新支援一個 value map: map[string]any 。
func (s *State) Default(key string, v any) any {
s.rwLock.Lock()
defer s.rwLock.Unlock()
_, ok := s.values[key]
if !ok {
s.values[key] = v
}
return s.values[key]
}
要使用時,使用者要傳一個初始化的指標進去,假如原本沒有設置,就會用那個值,假如已經有了,就會繼續使用之前的值。
type TODOList struct {
items []string
}
func (t *TODOList) add(item string) {
t.items = append(t.items, item)
}
// usage
todoList := p.State.Default("todoList", &TODOList{}).(*TODOList)
目前暫時沒有 generic function for struct,所以使用者還是要自己轉做 type assertions。
最後,一個只有新增功能的 TODO App 可以這樣寫:
package main
import (
_ "embed"
"fmt"
"log"
"github.com/mudream4869/toolgui/toolgui/tgcomp"
"github.com/mudream4869/toolgui/toolgui/tgexec"
"github.com/mudream4869/toolgui/toolgui/tgframe"
)
type TODOList struct {
items []string
}
func (t *TODOList) add(item string) {
t.items = append(t.items, item)
}
func Main(p *tgframe.Params) error {
tgcomp.Title(p.Main, "Example for Todo App")
todoList := p.State.Default("todoList", &TODOList{}).(*TODOList)
inp := tgcomp.Textbox(p.State, p.Main, "Add todo")
if tgcomp.Button(p.State, p.Main, "Add") {
todoList.add(inp)
}
for i, todo := range todoList.items {
tgcomp.TextWithID(p.Main,
fmt.Sprintf("%d: %s", i, todo),
fmt.Sprintf("todo_%d", i))
}
return nil
}